//
//  TabbarContentView.swift
//  Exchange
//
//  Created by rui on 2018/4/26.
//  Copyright © 2018年 common. All rights reserved.
//

import UIKit

protocol TabbarContentViewDelegate: class {
    func tabbarContent(contentView: TabbarContentView,fromIndex from: Int, toIndex to:Int)
}


class TabbarScrollView: UIScrollView {}

class TabbarContentView: UIView {
    
    lazy private var contentScroll: TabbarScrollView = {
        let content = TabbarScrollView()
        content.backgroundColor = UIColor.clear
        content.isPagingEnabled = true
        content.showsHorizontalScrollIndicator = false
        content.delegate = self
        content.showsVerticalScrollIndicator = false
        return content
    }()
    private var selectIndex: Int = 0
    private var layoutFlag: Bool = false
    var pages: [Any]!
    
    weak var delegate: TabbarContentViewDelegate?
    
    private var kWidth: CGFloat {
        get {
            return self.frame.size.width
        }
    }
    private var kHeight: CGFloat {
        get {
            return self.frame.size.height
        }
    }
    private var pagaData: [String:Any]?
    
    init(pages: [Any],pageData: [String:Any]? = nil) {
        super.init(frame: CGRect.zero)
        self.backgroundColor = UIColor.clear
        self.addSubview(contentScroll)
        self.layoutFlag = pages.count < 3
        self.pages = pages
        self.pagaData = pageData
        if self.layoutFlag {
            for idx in 0..<pages.count {
                if let pageController = getPageController(selectIndex: idx) {
                    self.contentScroll.addSubview(pageController)
                }
            }
        }
        if #available(iOS 11.0, *) {
            self.contentScroll.contentInsetAdjustmentBehavior = .never
        } else {
            // Fallback on earlier versions
        }
    }
    
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        self.contentScroll.frame = self.bounds
        layout()
    }
    
    func layout() {
        if self.layoutFlag {
            self.contentScroll.contentOffset = CGPoint(x: CGFloat(selectIndex) * kWidth, y: 0)
            for idx in 0..<self.pages.count {
                if let page = getPageController(selectIndex: idx) {
                    let rect = CGRect(x: CGFloat(idx) * kWidth, y: 0, width: kWidth, height: kHeight)
                    if rect != page.frame {
                       page.frame = rect
                    self.contentScroll.contentSize = CGSize(width: kWidth * CGFloat(self.pages.count), height: 0)
                    }
                }
            }
        }else {
            for subView in self.contentScroll.subviews {
                if let sub = subView as? TabbarPageController {
                    sub.removeFromSuperview()
                }
            }
            self.contentScroll.addSubview(self.getPreView()!)
            self.contentScroll.addSubview(self.getCurrentView()!)
            self.contentScroll.addSubview(self.getNextView()!)
            self.scrollToCenter()
        }
    }
    
    func scrollToCenter() {
        self.contentScroll.contentSize = CGSize(width: kWidth * 3.0, height: kHeight)
        self.contentScroll.contentOffset = CGPoint(x: kWidth, y: 0)
    }
    
    func preIndex() -> Int {
        var pre = selectIndex - 1
        if selectIndex == 0 {
            pre = pages.count - 1
        }
        return pre
    }
    
    func nextIndex() -> Int {
        var next = selectIndex + 1
        if selectIndex == pages.count - 1 {
            next = 0
        }
        return next
    }
    
    func getPreView() -> TabbarPageController? {
        guard let view = getPageController(selectIndex: preIndex()) else { return nil }
        view.frame = CGRect(x: 0, y: 0, width: kWidth, height: kHeight)
        return view
    }
    
    func getCurrentView() -> TabbarPageController? {
        guard let view = getPageController(selectIndex: selectIndex) else { return nil }
        view.frame = CGRect(x: kWidth, y: 0, width: kWidth, height: kHeight)
        return view
    }
    
    func getNextView() -> TabbarPageController? {
        guard let view = getPageController(selectIndex: nextIndex()) else { return nil }
        view.frame = CGRect(x: kWidth * 2.0, y: 0, width: kWidth, height: kHeight)
        return view
    }
    
    func getPageController(selectIndex index: Int) -> TabbarPageController? {
        guard  self.pages.count > index else {
            return nil
        }
        let pageContent = self.pages[index]
        if let page = pageContent as? TabbarPageController {
            page.pageData = self.pagaData
            return page
        }
        if let page = pageContent as? String {
            let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String
            if let pageClass = NSClassFromString(namespace + "." + page) as? TabbarPageController.Type
            {
                let pageController = pageClass.init()
                pageController.frame = self.bounds
                pageController.index = index
                pageController.pageData = self.pagaData
                pageController.viewDidLoad()
                pages.remove(at: index)
                pages.insert(pageController, at: index)
                return pageController
            }
        }
        return nil
    }
    
    func fouce(selectIndex index: Int) {
        if let prePage = self.pages[selectIndex] as? TabbarPageController {
            prePage.viewWillDisappear()
        }
        selectIndex = index
        layout()
        let selectPage = self.getPageController(selectIndex: index)
        selectPage?.viewWillAppear()
    }
    
    func layoutFouce(selectIndex index: Int) {
        selectIndex = index
        layout()
    }
    
    func caculateCurrentIndex(scrollOffset offset: CGPoint) {
        let preIndex = selectIndex
        var nextIndex = selectIndex
        if self.layoutFlag {
            nextIndex = Int(offset.x / kWidth)
        }else {
            if offset.x == 2 * kWidth {
                if nextIndex == self.pages.count - 1 {
                    nextIndex = 0
                }else {
                    nextIndex += 1
                }
            }else if offset.x == 0 {
                if nextIndex == 0 {
                    nextIndex = self.pages.count - 1
                }else {
                    nextIndex -= 1
                }
            }
        }
        if preIndex != nextIndex {
            fouce(selectIndex: nextIndex)
        }
        self.delegate?.tabbarContent(contentView: self, fromIndex: preIndex, toIndex: selectIndex)
    }
}

extension TabbarContentView : UIScrollViewDelegate {
    // MARK: - UIScrollViewDelegate
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        if scrollView == contentScroll {
            caculateCurrentIndex(scrollOffset: scrollView.contentOffset)
        }
    }
    
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        if scrollView == contentScroll {
            caculateCurrentIndex(scrollOffset: scrollView.contentOffset)
        }
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if scrollView == contentScroll && decelerate == false {
            caculateCurrentIndex(scrollOffset: scrollView.contentOffset)
        }
    }
}
